package com.lin.manager.notice.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lin.manager.common.enums.NoticeEnum;
import com.lin.manager.common.ex.BizException;
import com.lin.manager.common.req.QueryPage;
import com.lin.manager.common.resp.DataPage;
import com.lin.manager.common.user.UserInfoContextHolder;
import com.lin.manager.notice.NoticeMessageHelper;
import com.lin.manager.notice.dao.NoticeDao;
import com.lin.manager.notice.message.NoticeMessage;
import com.lin.manager.notice.model.dto.NoticeDTO;
import com.lin.manager.notice.model.dto.NoticeUserDTO;
import com.lin.manager.notice.model.entity.NoticeEntity;
import com.lin.manager.notice.model.vo.NoticeVO;
import com.lin.manager.notice.service.NoticeService;
import com.lin.manager.notice.service.NoticeUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @作者: 林江
 * @创建时间: 2024-04-10 19:11:15
 * @功能:
 */
@Slf4j
@Service
public class NoticeServiceImpl implements NoticeService {
    @Autowired
    private NoticeDao noticeDao;
    @Autowired
    private NoticeUserService noticeUserService;
    @Autowired
    private NoticeMessageHelper helper;

    @Override
    public DataPage<NoticeEntity> listCreatePage(QueryPage page) {
        LambdaQueryWrapper<NoticeEntity> wrapper = new QueryWrapper<NoticeEntity>().lambda().orderByDesc(NoticeEntity::getCreateTime)
                // 查询自己创建的
                .eq(NoticeEntity::getCreateBy, UserInfoContextHolder.getUserId()).and(StringUtils.isNotBlank(page.getKey()), condition -> condition.like(NoticeEntity::getTitle, page.getKey()).or().like(NoticeEntity::getContent, page.getKey()));

        Page<NoticeEntity> selectPage = noticeDao.selectPage(new Page<>(page.getPageNum(), page.getPageSize()), wrapper);
        return DataPage.<NoticeEntity>builder()
                .page(selectPage)
                .build();
    }

    @Override
    public DataPage<NoticeUserDTO> listRecivePage(QueryPage page) {
        Page<NoticeUserDTO> selectPage = noticeDao.listRecivePage(new Page<>(page.getPageNum(), page.getPageSize()), page.getKey(), page.getStatus(), UserInfoContextHolder.getUserId());
        return DataPage.<NoticeUserDTO>builder().page(selectPage).build();
    }

    @Override
    public void add(NoticeVO vo) {
        NoticeEntity notice = new NoticeEntity();
        BeanUtils.copyProperties(vo, notice);
        notice.setCreateUserName(UserInfoContextHolder.getUserInfo().getNickname());
        noticeDao.insert(notice);
        noticeUserService.insertNoticeUser(notice.getId(), vo.getNoticeUser());
    }

    @Override
    public void update(NoticeVO vo) {
        NoticeEntity notice = new NoticeEntity();
        BeanUtils.copyProperties(vo, notice);
        noticeDao.updateById(notice);
        noticeUserService.deleteByNoticeId(CollectionUtil.list(false, vo.getId()));
        noticeUserService.insertNoticeUser(notice.getId(), vo.getNoticeUser());
    }

    @Override
    public void del(Long[] ids) {
        noticeDao.deleteBatchIds(CollectionUtils.arrayToList(ids));
        noticeUserService.deleteByNoticeId(CollectionUtil.list(false, ids));
    }

    @Override
    public NoticeVO getById(Long id, Integer sign) {
        NoticeEntity noticeEntity = noticeDao.selectById(id);

        NoticeVO noticeVo = new NoticeVO();
        BeanUtils.copyProperties(noticeEntity, noticeVo);
        if (sign.equals(NumberUtils.INTEGER_ZERO)) {
            noticeVo.setNoticeUser(noticeUserService.listByNoticeId(id));
        }

        if (sign.equals(NumberUtils.INTEGER_ONE)) {
            noticeUserService.read(id);
        }
        return noticeVo;
    }

    @Override
    public void send(Long id) {
        NoticeEntity notice = noticeDao.selectById(id);
        Optional<NoticeEnum> optional = Arrays.stream(NoticeEnum.values()).filter(i -> i.getCode().equals(notice.getType())).findFirst();
        if (optional.isPresent()) {
            // 获取人员
            NoticeDTO noticeDto = buildNoticeDTO(notice);
            noticeDto.setUserIds(noticeUserService.listByNoticeId(id).stream().map(item -> item.getUserId()).collect(Collectors.toList()));

            NoticeMessage message = helper.get(notice.getType());
            message.send(noticeDto);
        } else {
            throw new BizException("系统不支持其他方式发送");
        }
    }

    @Override
    public Integer unread() {
        return noticeDao.unread(UserInfoContextHolder.getUserId());
    }

    /**
     * 建造通知信息
     *
     * @param notice
     * @return
     */
    private NoticeDTO buildNoticeDTO(NoticeEntity notice) {
        NoticeDTO dto = new NoticeDTO();
        dto.setTitle(notice.getTitle());
        dto.setContent(notice.getContent());
        dto.setType(notice.getType());
        dto.setSendStatus(notice.getSendStatus());
        return dto;
    }

}
